package gwtappcontainer.server.apps.insight;

import gwtappcontainer.server.apps.APIException;
import gwtappcontainer.server.apps.security.AccessController;
import gwtappcontainer.shared.apis.APIResponse;
import gwtappcontainer.shared.apis.APIResponse.Status;
import gwtappcontainer.shared.apps.insight.Center;
import gwtappcontainer.shared.apps.insight.Member;
import gwtappcontainer.shared.apps.insight.Member.ContactDetails;
import gwtappcontainer.shared.apps.insight.UnlistedProgram;

import java.util.ArrayList;

import javax.annotation.Nullable;
import javax.inject.Named;

import com.google.api.server.spi.config.Api;
import com.google.appengine.api.users.User;

@Api(name = "insight", 
scopes = { "https://www.googleapis.com/auth/userinfo.email" }
)
public class InsightAPI {		
	
	public APIResponse getAllCenters() {
		try {
			ArrayList<Center> centers = CenterRepository.getAll();
			
			return new APIResponse(Status.SUCCESS, centers);
		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}
	
	public APIResponse addMember(@Named("email") String email, 
			@Nullable @Named("first_name") String firstName,
			@Nullable @Named("middle_name") String middleName,			
			@Nullable @Named("last_name") String lastName,
			@Named("owning_center_id") int owningCenterId,
			@Nullable @Named("phone") String phone,
			@Nullable @Named("home_address") String homeAddress,
			@Nullable @Named("office_address") String officeAddress,
			@Nullable @Named("home_phone") String homePhone,
			@Nullable @Named("office_phone") String officePhone,
			@Nullable @Named("singapore_nric") String singaporeNRIC,
			User user
			) {
		
		try {
			AccessController.ensureLoggedin(user);
			
			ContactDetails contactDetails = new Member.ContactDetails();
			contactDetails.email = email;
			contactDetails.firstName = firstName;
			contactDetails.middleName = middleName;
			contactDetails.lastName = lastName;
			contactDetails.phone = phone;
			contactDetails.homeAddress = homeAddress;
			contactDetails.officeAddress = officeAddress;
			contactDetails.homePhone = homePhone;
			contactDetails.officePhone = officePhone;
			contactDetails.singaporeNRIC = singaporeNRIC;
					
			MemberRepository.add(contactDetails, owningCenterId, user.getEmail());
			
			return new APIResponse(Status.SUCCESS, "Successfully added member [" + contactDetails.email + "]");
		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}
	
	public APIResponse updateMember(@Named("member_id") int memberId, 
			@Nullable @Named("email") String email, 
			@Nullable @Named("first_name") String firstName,
			@Nullable @Named("middle_name") String middleName,			
			@Nullable @Named("last_name") String lastName,
			@Named("owning_center_id") int owningCenterId,
			@Nullable @Named("phone") String phone,
			@Nullable @Named("home_address") String homeAddress,
			@Nullable @Named("office_address") String officeAddress,
			@Nullable @Named("home_phone") String homePhone,
			@Nullable @Named("office_phone") String officePhone,
			@Nullable @Named("singapore_nric") String singaporeNRIC,
			User user
			) {		
		try {
			AccessController.ensureLoggedin(user);
			
			Member member = MemberRepository.get(memberId, user.getEmail());
			
			if (null == member)
				throw new APIException(Status.ERROR_RESOURCE_DOES_NOT_EXIST, 
						"Unable to find member with id [" + memberId + "]");
			
			ContactDetails contactDetails = member.contactDetails;
			
			if (email != null) contactDetails.email = email;
			if (firstName != null) contactDetails.firstName = firstName;
			if (middleName != null) contactDetails.middleName = middleName;
			if (lastName != null) contactDetails.lastName = lastName;
			if (phone != null) contactDetails.phone = phone;
			if (homeAddress != null) contactDetails.homeAddress = homeAddress;
			if (officeAddress != null) contactDetails.officeAddress = officeAddress;
			if (homePhone != null) contactDetails.homePhone = homePhone;
			if (officePhone != null) contactDetails.officePhone = officePhone;
			if (singaporeNRIC != null) contactDetails.singaporeNRIC = singaporeNRIC;
							
			MemberRepository.updateContactDetails(memberId, contactDetails, user.getEmail());
			
			return new APIResponse(Status.SUCCESS, "Successfully updated member with [" + member.id + "]");			
		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}
	
	public APIResponse getMember(@Named("email") String email, User user) {
		try {
			AccessController.ensureLoggedin(user);
			Member member = MemberRepository.get(email, user.getEmail());
			
			return new APIResponse(Status.SUCCESS, member);
		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}
	
	public APIResponse addUnlistedProgramToMember(@Named("member_id") int memberId, 
			@Named("program_type_id") int programTypeId,
			@Nullable @Named("venue") String venue,
			@Nullable @Named("month") int month,
			@Nullable @Named("year") int year,
			@Nullable @Named("teacher") String teacher,	User user) {		
		try {
			AccessController.ensureLoggedin(user);
			
			UnlistedProgram unlistedProgram = new UnlistedProgram();
			unlistedProgram.programTypeId = programTypeId;
			unlistedProgram.venue = venue;
			unlistedProgram.month = month;
			unlistedProgram.year = year;
			unlistedProgram.teacher = teacher;
			
			MemberRepository.addUnlistedProgram(memberId, unlistedProgram, user.getEmail());
			
			return new APIResponse(Status.SUCCESS, "Unlisted program added to member");		
		} catch (Exception ex) {
			return new APIResponse(ex);
		}				
	}
	
	public APIResponse deleteUnlistedProgram(@Named("unlisted_program_id") int unlistedProgramId, 
			User user) {		
		try {
			AccessController.ensureLoggedin(user);
			
			MemberRepository.deleteUnlistedProgram(unlistedProgramId, user.getEmail());						
			
			return new APIResponse(Status.SUCCESS, 
					"Unlisted program [" + unlistedProgramId + "] deleted");		
		} catch (Exception ex) {
			return new APIResponse(ex);
		}				
	}
	
	public APIResponse listProgramTypes() {
		try {
			return new APIResponse(Status.SUCCESS, ProgramTypeRepository.getAll());
		} catch (Exception ex) {
			return new APIResponse(ex);
		}
	}
		
}

